﻿using HslCommunication;
using HslCommunication.Profinet.Melsec;
using MyPLC.Config;
using MyPLC.Entity;
using MyPLC.Helper;
using System;
using System.Threading;

namespace MyPLC.Services
{
    public class PLCService
    {
        private static Dapper dapper = new Dapper();
        private MelsecMcNet melsec_net;
        private OperateResult connect;
        private IPConfig config;
        public PLCService(string device, string ip,  int port)
        {
            try
            {
                config = new IPConfig() {
                    IP = ip,
                    Device = device,
                    Port = port,
                    IPAddress = string.Format("{0}:{1}",ip,port),
                    tbl_set = dapper.GetSetInfo(string.Format("{0}:{1}", ip, port))
                };

                melsec_net = new MelsecMcNet(ip, port);
                melsec_net.ConnectTimeOut = 3000; // 网络连接的超时时间

                //melsec_net.NetworkNumber = networkNumber;  // 网络号 0x00
                //melsec_net.NetworkStationNumber = networkStationNumber; // 网络站号 0x00

                connect = melsec_net.ConnectServer();
                if (connect.IsSuccess)
                {
                    LoggerHelper.Info(string.Format("设备：{0} {1},连接成功！",device, ip));
                }
                else
                {
                    LoggerHelper.Info(string.Format("设备：{0} {1},连接失败！", device, ip));
                }
            }
            catch (Exception ex)
            {
                LoggerHelper.Error(ex);
            }
        }
        /// <summary>
        /// 测试连接是否成功
        /// </summary>
        /// <returns></returns>
        public bool ConnectSuccess()
        {
            return connect != null && connect.IsSuccess;
        }

        #region 写入测试
        public void Write()
        {
            LoggerHelper.Info("Write");
            if (connect.IsSuccess)
            {
                short value = 12;
                OperateResult res = melsec_net.Write("D1029", value);

                LoggerHelper.Info(string.Format("D1029 WriteResult:{0}", res.IsSuccess));

                LoggerHelper.Info(JsonHelper.SerializeObject(res));

                value = 31;
                res = melsec_net.Write("D3012", value);

                LoggerHelper.Info(string.Format("D3012 WriteResult:{0}", res.IsSuccess));

            }
        }
        #endregion

        /// <summary>
        /// 采集温度信号 5分钟一次
        /// </summary>
        public void SyncSignalOrderInvoke()
        {
            while (true)
            {
                try
                {
                    //同步数据
                    RetryHelper.Execute<bool>("SyncSignalOrderInvoke", () =>
                    {
                        return PLCSignalOrderTrace();
                    }, config, false, 1, () => Thread.Sleep(1000));
                }
                catch (Exception ex)
                {
                    LoggerHelper.Error(ex);
                }
                if(config.tbl_set != null)
                {
                    Thread.Sleep(config.tbl_set.WDPL * 1000);
                }
                else
                {
                    Thread.Sleep(AppConfig.SyncSeconds * 1000);
                }
            }
        }
        public bool PLCSignalOrderTrace()
        {
            if (connect.IsSuccess)
            {
                tbl_signalorder model = new tbl_signalorder();
                model.D1029 = ReadInt32("D1029");
                model.D1030 = ReadInt32("D1030");
                model.D1031 = ReadInt32("D1031");
                model.D1032 = ReadInt32("D1032");
                model.D1033 = ReadInt32("D1033");
                model.D1034 = ReadInt32("D1034");
                model.D1035 = ReadInt32("D1035");
                model.D1036 = ReadInt32("D1036");
                model.D1037 = ReadInt32("D1037");
                model.D1038 = ReadInt32("D1038");
                model.D1039 = ReadInt32("D1039");
                model.D1535 = ReadInt32("D1535");
                model.D1370 = ReadString("D1370", 10);
                model.CREATEDATE = DateTime.Now;
                model.IPAddress = string.Format("{0}:{1}",config.IP,config.Port);
                LoggerHelper.Info(string.Format("PLCSignalOrderData:{0}", JsonHelper.SerializeObject(model)));
                //写入数据库
                return dapper.CreateSignalOrder(model);
            }
            else
            {
                LoggerHelper.Info(string.Format("设备：{0} {1},连接失败！", config.Device, config.IP));

                melsec_net = new MelsecMcNet(config.IP, config.Port);
                melsec_net.ConnectTimeOut = 3000; // 网络连接的超时时间
                //melsec_net.NetworkNumber = config.NetworkNumber;  // 网络号
                //melsec_net.NetworkStationNumber = config.NetworkStationNumber; // 网络站号
                connect = melsec_net.ConnectServer();
                throw new Exception("连接失败！");
            }
        }

        /// <summary>
        /// IO振动压力信号采集 60秒一次
        /// </summary>
        public void SyncZDYLOrderInvoke()
        {
            while (true)
            {
                try
                {
                    //同步数据
                    RetryHelper.Execute<bool>("SyncZDYLOrderInvoke", () =>
                    {
                        return PLCZDYLOrderTrace();
                    }, config, false, 1, () => Thread.Sleep(1000));
                }
                catch (Exception ex)
                {
                    LoggerHelper.Error(ex);
                }
                Thread.Sleep(AppConfig.SyncMilliSeconds);
            }
        }
        public bool PLCZDYLOrderTrace()
        {
            if (connect.IsSuccess)
            {
                int M200 = ReadInt32(config.tbl_set.ZDYLPL);
                LoggerHelper.Info(string.Format("M200：{0}", M200));
                if (M200 > 0)
                {
                    tbl_zdylorder model = new tbl_zdylorder();
                    model.D3012 = ReadInt32("D3012");
                    model.D3015 = ReadInt32("D3015");
                    model.D3018 = ReadInt32("D3018");
                    model.D3021 = ReadInt32("D3021");
                    model.D3031 = ReadDecimal("D3031", AppConfig.Offset);
                    model.D3032 = ReadDecimal("D3032", AppConfig.Offset);
                    model.D3029 = ReadDecimal("D3029", AppConfig.Offset);
                    model.D3030 = ReadDecimal("D3030", AppConfig.Offset);
                    model.D1370 = ReadString("D1370", 10);
                    model.CREATEDATE = DateTime.Now;
                    model.IPAddress = string.Format("{0}:{1}", config.IP, config.Port);
                    LoggerHelper.Info(string.Format("M200：{0}, PLCZDYLOrderData:{1}", M200, JsonHelper.SerializeObject(model)));
                    //写入数据库
                    dapper.CreateZDYLOrder(model);
                }
                return M200 > 0;
            }
            else
            {
                LoggerHelper.Info(string.Format("IP:{0}:{1},连接失败！", config.IP, config.Port));

                melsec_net = new MelsecMcNet(config.IP, config.Port);
                melsec_net.ConnectTimeOut = 3000; // 网络连接的超时时间
                //melsec_net.NetworkNumber = config.NetworkNumber;  // 网络号
                //melsec_net.NetworkStationNumber = config.NetworkStationNumber; // 网络站号
                connect = melsec_net.ConnectServer();
                throw new Exception("连接失败！");
            }
        }

        /// <summary>
        /// IO电磁流信号采集
        /// </summary>
        public void SyncRealOrderInvoke()
        {
            while (true)
            {
                try
                {
                    //同步数据
                    RetryHelper.Execute<bool>("SyncOrderInvoke", () =>
                    {
                        return PLCRealOrderTrace();
                    }, config, false, 1, () => Thread.Sleep(1000));
                }
                catch (Exception ex)
                {
                    LoggerHelper.Error(ex);
                }
                Thread.Sleep(AppConfig.SyncMilliSeconds);
            }
        }
        public bool PLCRealOrderTrace()
        {
            if (connect.IsSuccess)
            {
                int M204 = ReadInt32(config.tbl_set.DCLPL);
                LoggerHelper.Info(string.Format("M204：{0}", M204));
                if (M204 > 0)
                {
                    tbl_realorder model = new tbl_realorder();
                    model.D1000 = ReadDecimal("D1000", AppConfig.Offset);
                    model.D1001 = ReadDecimal("D1001", AppConfig.Offset);
                    model.D1002 = ReadDecimal("D1002", AppConfig.Offset);
                    model.D1003 = ReadDecimal("D1003", AppConfig.Offset);
                    model.D1004 = ReadDecimal("D1004", AppConfig.Offset);
                    model.D1005 = ReadDecimal("D1005", AppConfig.Offset);
                    model.D1006 = ReadDecimal("D1006", AppConfig.Offset);
                    model.D1007 = ReadDecimal("D1007", AppConfig.Offset);
                    model.D1370 = ReadString("D1370", 10);
                    model.CREATEDATE = DateTime.Now;
                    model.IPAddress = string.Format("{0}:{1}", config.IP, config.Port);
                    LoggerHelper.Info(string.Format("M204:{0},PLCRealOrderData:{1}",M204, JsonHelper.SerializeObject(model)));
                    //写入数据库
                    return dapper.CreateRealOrder(model);
                }
                return M204 > 0;
            }
            else
            {
                LoggerHelper.Info(string.Format("IP:{0}:{1},连接失败！", config.IP, config.Port));

                melsec_net = new MelsecMcNet(config.IP, config.Port);
                melsec_net.ConnectTimeOut = 3000; // 网络连接的超时时间
                //melsec_net.NetworkNumber = config.NetworkNumber;  // 网络号
                //melsec_net.NetworkStationNumber = config.NetworkStationNumber; // 网络站号
                connect = melsec_net.ConnectServer();
                throw new Exception("连接失败！");
            }
        }

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public int ReadInt32(string address)
        {
            return RetryHelper.Execute<int>("ReadInt32", () =>
            {
                OperateResult<int> op = melsec_net.ReadInt32(address);
                if (op.IsSuccess)
                {
                    return op.Content;
                }
                else
                {
                    LoggerHelper.Info(op.Message);
                    return 0;
                }
            }, config, 0, 2, () => Thread.Sleep(100));
        }
        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public decimal ReadDecimal(string address, decimal offset = 0.0M)
        {
            return RetryHelper.Execute<decimal>("ReadDecimal", () =>
            {
                OperateResult<int> op = melsec_net.ReadInt32(address);
                if (op.IsSuccess)
                {
                    if (offset > 0)
                    {
                        return Convert.ToDecimal((op.Content / offset).ToString("F2"));
                    }
                    return Convert.ToDecimal(op.Content);
                }
                else
                {
                    LoggerHelper.Info(op.Message);
                    return 0;
                }
            }, config, 0, 2, () => Thread.Sleep(100));
        }
        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public string ReadString(string address, ushort length)
        {
            return RetryHelper.Execute<string>("GetReadString", () =>
            {
                OperateResult<string> op = melsec_net.ReadString(address, length);
                if (op.IsSuccess)
                {
                    return op.Content;
                }
                else
                {
                    LoggerHelper.Info(op.Message);
                    return string.Empty;
                }
            }, config, string.Empty, 2, () => Thread.Sleep(100));
        }

        /// <summary>
        /// 同步数据
        /// </summary>
        public void SyncOrderInvoke()
        {
            while (true)
            {
                try
                {
                    //同步数据
                    RetryHelper.Execute<bool>("SyncOrderInvoke", () =>
                    {
                        return PLCTrace();
                    }, config, false, 3, () => Thread.Sleep(200));
                }
                catch (Exception ex)
                {
                    LoggerHelper.Error(ex);
                }
                Thread.Sleep(AppConfig.SyncMilliSeconds);
            }
        }
        public bool PLCTrace()
        {
            if (connect.IsSuccess)
            {
                tbl_order model = new tbl_order();
                model.D1082 = ReadInt32ToString("D1082");
                model.D3013 = ReadInt32ToString("D3013");
                model.D3014 = ReadInt32ToString("D3014");
                model.D3016 = ReadInt32ToString("D3016");
                model.D3017 = ReadInt32ToString("D3017");
                model.D3019 = ReadInt32ToString("D3019");
                model.D3020 = ReadInt32ToString("D3020");
                model.D3022 = ReadInt32ToString("D3022");
                model.D3023 = ReadInt32ToString("D3023");
                model.D3000 = ReadInt32ToString("D3000");
                model.D1077 = ReadInt32ToString("D1077");
                model.D1370 = ReadInt32ToString("D1370");
                model.D3122 = ReadInt32ToString("D3122");
                model.D1009 = ReadInt32ToString("D1009");
                model.D1029 = ReadInt32ToString("D1029");
                model.D1030 = ReadInt32ToString("D1030");
                model.D1535 = ReadInt32ToString("D1535");
                model.D1031 = ReadInt32ToString("D1031");
                model.D1032 = ReadInt32ToString("D1032");
                model.D1033 = ReadInt32ToString("D1033");
                model.D1034 = ReadInt32ToString("D1034");
                model.D1035 = ReadInt32ToString("D1035");
                model.D1036 = ReadInt32ToString("D1036");
                model.D1037 = ReadString("D1037", 10);//部署番号
                model.D1038 = ReadInt32ToString("D1038");
                model.D1039 = ReadInt32ToString("D1039");
                model.D1000 = ReadInt32ToString("D1000");
                model.D1001 = ReadInt32ToString("D1001");
                model.D1002 = ReadInt32ToString("D1002");
                model.D1003 = ReadInt32ToString("D1003");
                model.D1005 = ReadInt32ToString("D1005");
                model.D1006 = ReadInt32ToString("D1006");
                model.D1380 = ReadInt32ToString("D1380");
                model.D3142 = ReadInt32ToString("D3142");
                model.D3141 = ReadInt32ToString("D3141");
                model.D3140 = ReadInt32ToString("D3140");
                model.D3145 = ReadInt32ToString("D3145");
                model.D3461 = ReadInt32ToString("D3461");
                model.CREATEDATE = DateTime.Now;
                model.IPAddress = string.Format("{0}:{1}", config.IP, config.Port);
                LoggerHelper.Info(string.Format("PLCData:{0}", JsonHelper.SerializeObject(model)));
                if (!string.IsNullOrWhiteSpace(model.D1037))
                {
                    return dapper.CreateOrder(model);
                }
                else
                {
                    LoggerHelper.Info(string.Format("IP:{0}:{1},部署番号为空!", config.IP, config.Port));
                    return false;
                }
            }
            else
            {
                LoggerHelper.Info(string.Format("设备：{0} {1},连接失败！", config.Device, config.IP));

                melsec_net = new MelsecMcNet(config.IP, config.Port);
                melsec_net.ConnectTimeOut = 3000; // 网络连接的超时时间
                //melsec_net.NetworkNumber = config.NetworkNumber;  // 网络号
                //melsec_net.NetworkStationNumber = config.NetworkStationNumber; // 网络站号
                connect = melsec_net.ConnectServer();
                throw new Exception("连接失败！");
            }
        }
        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public string ReadInt32ToString(string address, decimal offset = 0.0M)
        {
            return RetryHelper.Execute<string>("ReadInt32ToString", () =>
            {
                OperateResult<int> op = melsec_net.ReadInt32(address);
                if (op.IsSuccess)
                {
                    if (offset > 0)
                    {
                        return (op.Content / offset).ToString("F2");
                    }
                    return op.Content.ToString();
                }
                else
                {
                    LoggerHelper.Info(op.Message);
                    return string.Empty;
                }
            }, config, string.Empty, 2, () => Thread.Sleep(100));
        }
    }
}
